import { useState, useEffect, useRef } from 'react';
import { message } from 'antd';
import { experimentApi, projectApi } from '../services/api';
import { ExperimentRun, ExperimentFullData, Project, ExperimentUpdate } from '../types';

/**
 * 管理实验数据加载的自定义 Hook
 */
export const useExperimentData = (projectId: string | undefined) => {
  const [project, setProject] = useState<Project | null>(null);
  const [experiments, setExperiments] = useState<ExperimentRun[]>([]);
  const [selectedExperiment, setSelectedExperiment] = useState<ExperimentFullData | null>(null);
  const [loading, setLoading] = useState(true);
  const [detailLoading, setDetailLoading] = useState(false);
  
  // 使用ref存储最新的experiments列表，避免闭包问题
  const experimentsRef = useRef<ExperimentRun[]>([]);
  
  // 同步ref和state
  useEffect(() => {
    experimentsRef.current = experiments;
  }, [experiments]);

  // 加载项目信息和实验列表
  useEffect(() => {
    const loadData = async () => {
      if (!projectId) return;

      try {
        setLoading(true);

        // 加载项目信息
        const projectData = await projectApi.getProjectByName(projectId);
        setProject(projectData);

        // 加载实验列表
        const experimentsList = await experimentApi.getExperiments(projectId);
        setExperiments(experimentsList);
      } catch (error: any) {
        console.error('Failed to load data:', error);
        message.error('加载数据失败');
      } finally {
        setLoading(false);
      }
    };

    loadData();
  }, [projectId]);

  // 加载选中的实验详情
  const handleSelectExperiment = async (experiment: ExperimentRun) => {
    if (!projectId) return;

    // 使用ref获取最新的experiments列表，检查实验是否还在列表中
    const currentExperiments = experimentsRef.current;
    const experimentExists = currentExperiments.some(exp => exp.id === experiment.id);
    
    if (!experimentExists) {
      setSelectedExperiment(null);
      return;
    }

    try {
      setDetailLoading(true);
      const detail = await experimentApi.getExperimentDetail(projectId, experiment.id);
      
      // 再次检查实验是否还在列表中（可能在请求过程中被删除）
      const stillExists = experimentsRef.current.some(exp => exp.id === experiment.id);
      if (stillExists) {
        setSelectedExperiment(detail);
      } else {
        setSelectedExperiment(null);
      }
    } catch (error: any) {
      // 如果是404错误（实验不存在），静默处理，不显示错误消息，并移除该实验
      if (error.response?.status === 404) {
        setSelectedExperiment(null);
        // 从列表中移除不存在的实验
        setExperiments(prevExperiments => prevExperiments.filter(exp => exp.id !== experiment.id));
      } else {
        console.error('Failed to load experiment detail:', error);
        message.error('加载实验详情失败');
        setSelectedExperiment(null);
      }
    } finally {
      setDetailLoading(false);
    }
  };

  // 刷新实验列表
  const refreshExperiments = async () => {
    if (!projectId) return;

    try {
      const experimentsList = await experimentApi.getExperiments(projectId);
      setExperiments(experimentsList);
      
      // 使用函数式更新来检查当前选中的实验是否还在列表中
      setSelectedExperiment(prevSelected => {
        if (!prevSelected) return null;
        const stillExists = experimentsList.some(exp => exp.id === prevSelected.id);
        return stillExists ? prevSelected : null;
      });
    } catch (error: any) {
      console.error('Failed to refresh experiments:', error);
      message.error('刷新实验列表失败');
    }
  };

  // 从列表中移除指定的实验（乐观更新）
  const removeExperimentFromList = (experimentId: number) => {
    setExperiments(prevExperiments => prevExperiments.filter(exp => exp.id !== experimentId));
    setSelectedExperiment(prevSelected => {
      if (prevSelected?.id === experimentId) {
        return null;
      }
      return prevSelected;
    });
  };

  // 更新实验基础信息
  const updateExperimentBasicInfo = async (experimentId: number, payload: ExperimentUpdate) => {
    if (!projectId) {
      return null;
    }

    try {
      const updated = await experimentApi.updateExperiment(projectId, experimentId, payload);

      setExperiments(prevExperiments =>
        prevExperiments.map(exp => (exp.id === experimentId ? { ...exp, ...updated } : exp))
      );

      setSelectedExperiment(prevSelected => {
        if (!prevSelected || prevSelected.id !== experimentId) {
          return prevSelected;
        }
        return {
          ...prevSelected,
          name: updated.name,
          description: updated.description,
        };
      });

      return updated;
    } catch (error: any) {
      console.error('Failed to update experiment:', error);
      message.error(error.response?.data?.detail || '更新实验信息失败');
      throw error;
    }
  };

  return {
    project,
    experiments,
    selectedExperiment,
    loading,
    detailLoading,
    setSelectedExperiment,
    handleSelectExperiment,
    refreshExperiments,
    removeExperimentFromList,
    updateExperimentBasicInfo,
  };
};

